﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace md.imi.membrane.common.DataStructures
{

    public delegate void TreeVisitor<T>(T nodeData);

    // each node
    public class Tree<T> : IDisposable
    {
        // the Id used to unically indentify an object. Widely used for cashing
        public Guid ID { get; set; }
        public T Data { get; set; }
        public LinkedList<Tree<T>> children;

        public Tree ()
        {
            ID = Guid.NewGuid();
            Data = default(T);
            this.children = null;
        }

        public Tree(T data)
        {
            this.Data = data;
            children = new LinkedList<Tree<T>>();
        }

        public void addChild(T data)
        {
            children.AddFirst(new Tree<T>(data));
        }

        public Tree<T> getChild(int i)
        {
            foreach (Tree<T> n in children)
                if (--i == 0) return n;
            return null;
        }

        public void traverse(Tree<T> node, TreeVisitor<T> visitor)
        {
            visitor(this.Data);
            foreach (Tree<T> kid in this.children)
                traverse(kid, visitor);
        }

        /// <summary>
        ///     Return a list with pointers to all leaf tree nodes.
        /// The leaf nodes are ued as last system state for all evaluations, 
        /// and offer the possibility to contine running on all branches
        /// </summary>
        /// <returns></returns>
        public List<Tree<T>> getAllLeafNodes()
        {
            return null;
        }

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion

        public List<T> getAllChildrens(T node)
        {
            return null;
        }
    }
}
